/*
 * Map.h
 *
 *  Created on: Jan 22, 2011
 *      Author: kmueller
 */

#ifndef MAPWIDGET_H_
#define MAPWIDGET_H_

#include "../core/Opennav.h"

#include <QDateTime>
#include <QGeoCoordinate>
#include <QImage>
#include <QMutex>
#include <QPainter>
#include <QPoint>
#include <QThread>
#include <QTimer>

#include <QWidget>

class LabeledCoordinate;
class ExtendedGeoPositionInfo;
class MainWindow;
class MapPainter;
class CircleGesture;
class MoveGesture;

class MapWidget;

class ShadowRenderer: protected QThread {
	Q_OBJECT

	public:
		ShadowRenderer(MapWidget* parent);
		~ShadowRenderer();

	public slots:
		void update();

	signals:
		void renderingFinished();

	protected:
		void run();
	private:

		opennav::MapRenderer* renderer;
		bool update_;
		QMutex mutex;
	};

class MapWidget: public QWidget {
Q_OBJECT

friend class ShadowRenderer;

private:
	class FieldOfView {
	public:
		FieldOfView();
		void setCenter(const QPoint& center);
		void setCenter(const int x, const int y);
		void setViewportSize(const QSize& size);
		void setViewportSize(const int width, const int height);
		void setOriginalSize(const QSize& size);
		void setOriginalSize(const int width, const int height);
		void move(const QPoint& offset);
		QPoint getStartPoint() const;
		QSize getViewportSize() const;
		QPoint translatePoint(const QPoint& point);
		QPoint translatePoint(const int x, const int y);

	private:
		QSize viewportSize;
		QSize originalSize;
		QPoint center;
	};

	class ZoomHandler{

	public:
		enum ZoomDirection{ZoomIn, ZoomOut};
		ZoomHandler();
		void handle(ZoomDirection direction, int& zoomLevel);
	private:
		QTimer timer;
		QDateTime start;
	};

public:
	MapWidget(MainWindow* parent);
	~MapWidget();
	QtMobility::QGeoCoordinate getCenter() const;

public slots:
	void setCenter(const LabeledCoordinate& c);
	void setCenter(const QtMobility::QGeoCoordinate& c);
	void setCurrentPosition(const ExtendedGeoPositionInfo *);
	void rerender();

protected:
	//	bool event ( QEvent * ) ;
	void mouseDoubleClickEvent(QMouseEvent *event);
	void mouseMoveEvent(QMouseEvent *event);
	void mousePressEvent(QMouseEvent *event);
	void mouseReleaseEvent(QMouseEvent *event);
	void resizeEvent(QResizeEvent *event);
	void paintEvent(QPaintEvent *event);

private slots:
	void moveCenter(const QPoint offset);
	void moveMap(const QPoint c);
	void zoomIn();
	void zoomOut();
	//	void setOrigin(const LabeledCoordinate&);
	//	void setDestination(const LabeledCoordinate&);

private:
	QtMobility::QGeoCoordinate getPointCoordinate(opennav::Point& point);
	QtMobility::QGeoCoordinate getPointCoordinate(const QPoint& point);
	QtMobility::QGeoCoordinate getEventCoordinate(QMouseEvent* event);

	int zoomLevel;
	QtMobility::QGeoCoordinate center;
	const ExtendedGeoPositionInfo *current;

	MainWindow* mainwindow;
	//	QPainter* mapPainter;
	//	MapPainter* painter;
	CircleGesture* circleGesture;
	MoveGesture* moveGesture;

	QMutex transMutex;
	opennav::Transformation transformation;

	ShadowRenderer* render;
	QImage shadow;
	FieldOfView shadowFOV;
	QMutex renderMutex;
	ZoomHandler zoomHandler;
};

#endif /* MAP_H_ */
